package com.example.config.redis;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author LiYuhang
 * @version 0.1
 * @application
 * @Date 2021/5/26 18:39
 * @Description TODO
 */
@Configuration
public class CommonPoolConfig {


    @Bean(name = "forkJoinPool")
    public ExecutorService forkJoinPool() {
        return new ForkJoinPool();
    }


    /**
     * 核心线程
     */
    private int corePoolSize=Runtime.getRuntime().availableProcessors() + 1 ;

    /**
     * 最大线程
     */
    @Value("${async.executor.thread.max_pool_size:#{128}}")
    private int maxPoolSize;
    /**
     * 队列长度
     */
    @Value("${async.executor.thread.queue_capacity:#{999999}}")
    private int queueCapacity;

    /**
     * 内容数据用线程池
     * @return
     */
    @Bean(name = "taskExecutor")
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = getThreadPoolTaskExecutor("simpleAsync-");
        return executor;
    }

    /**
     * 创建异步线程池
     * @param namePrefix
     * @return
     */
    private ThreadPoolTaskExecutor getThreadPoolTaskExecutor(String namePrefix) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 配置核心线程数
        executor.setCorePoolSize(corePoolSize);
        // 配置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 配置队列大小
        executor.setQueueCapacity(queueCapacity);
        // 配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix(namePrefix);

        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 执行初始化
        executor.initialize();
        return executor;
    }

    /**
     * 评论数据用线程池
     * @return
     */
    @Bean(name = "taskExecutorStream")
    public TaskExecutor taskExecutorStream() {
        ThreadPoolTaskExecutor executor = getThreadPoolTaskExecutor("streamAsync-");
        return executor;
    }


    @Bean(name = "taskExecutorPubSub")
    public TaskExecutor taskExecutorPubSub() {
        ThreadPoolTaskExecutor executor = getThreadPoolTaskExecutor("pubSubAsync-");
        return executor;
    }

    /**
     * @Description: 定时任务调度器
     * @Author: LiYuhang
     */
    @Bean
    public TaskScheduler scheduledExecutorService() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(4);
        scheduler.setThreadNamePrefix("scheduled-");
        return scheduler;
    }

}
